package zelix.hack.hacks;

import zelix.hack.Hack;
import zelix.hack.HackCategory;
import zelix.value.BooleanValue;
import zelix.value.NumberValue;
import zelix.utils.Wrapper;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.item.EntityItemFrame;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraftforge.client.event.MouseEvent;

import java.util.List;
import java.util.Random;

public class Reach extends Hack {

	static BooleanValue throughBlocks;
	static NumberValue reachMinVal;
	static NumberValue reachMaxVal;
	static BooleanValue bypassMAC;
	public  Random r;
	public Reach() {
		super("Reach", HackCategory.COMBAT);
		reachMinVal=new NumberValue("ReachMin", 3D, 3D, 6D);
		reachMaxVal=new NumberValue("ReachMax", 3D, 3D, 6D);
		throughBlocks=new BooleanValue("ThroughBlocks", false);
		r = new Random();
		addValue(throughBlocks,reachMinVal,reachMaxVal,bypassMAC);
	}

	@Override
	public void onMouse(MouseEvent event) {

		if (!throughBlocks.getValue() && Wrapper.INSTANCE.mc().objectMouseOver != null && Wrapper.INSTANCE.mc().objectMouseOver.typeOfHit != null && Wrapper.INSTANCE.mc().objectMouseOver.typeOfHit == RayTraceResult.Type.BLOCK) {
			return;
		}
		double range = reachMinVal.getValue() + r.nextDouble() * (reachMaxVal.getValue() - reachMinVal.getValue());
		Object[] mouseOver = Reach.getMouseOver(range, 0.0, 0.0f);
		if (mouseOver == null) {
			return;
		}
		Vec3d lookVec = Wrapper.INSTANCE.player().getLookVec();
		Wrapper.INSTANCE.mc().objectMouseOver = new RayTraceResult((Entity) mouseOver[0], (Vec3d) mouseOver[1]);
		Wrapper.INSTANCE.mc().pointedEntity = (Entity) mouseOver[0];

		super.onMouse(event);
	}


	public static Object[] getMouseOver(double Range, double bbExpand, float f) {
		Entity renderViewEntity = Wrapper.INSTANCE.mc().getRenderViewEntity();
		Entity entity = null;
		if (renderViewEntity == null || Wrapper.INSTANCE.world() == null) {
			return null;
		}
		Wrapper.INSTANCE.mc().mcProfiler.startSection("pick");
		Vec3d positionEyes = renderViewEntity.getPositionEyes(0.0f);
		Vec3d renderViewEntityLook = renderViewEntity.getLook(0.0f);
		Vec3d vector = positionEyes.addVector(renderViewEntityLook.x * Range, renderViewEntityLook.y * Range, renderViewEntityLook.z * Range);
		Vec3d ve = null;
		List entitiesWithinAABB = Wrapper.INSTANCE.world().getEntitiesWithinAABBExcludingEntity(renderViewEntity, renderViewEntity.getEntityBoundingBox().expand(renderViewEntityLook.x * Range, renderViewEntityLook.y * Range, renderViewEntityLook.z * Range).expand(1.0, 1.0, 1.0));
		double range = Range;
		for (int i = 0; i < entitiesWithinAABB.size(); ++i) {
			double v;
			Entity e = (Entity)entitiesWithinAABB.get(i);
			if (!e.canBeCollidedWith()) continue;
			float size = e.getCollisionBorderSize();
			AxisAlignedBB bb = e.getEntityBoundingBox().expand((double)size, (double)size, (double)size);
			bb = bb.expand(bbExpand, bbExpand, bbExpand);
			RayTraceResult objectPosition = bb.calculateIntercept(positionEyes, vector);
			if (bb.contains(positionEyes)) {
				if (!(0.0 < range) && range != 0.0) continue;
				entity = e;
				ve = objectPosition == null ? positionEyes : objectPosition.hitVec;
				range = 0.0;
				continue;
			}
			if (objectPosition == null || !((v = positionEyes.distanceTo(objectPosition.hitVec)) < range) && range != 0.0) continue;
			boolean b = false;
			if (e == renderViewEntity.getRidingEntity()) {
				if (range != 0.0) continue;
				entity = e;
				ve = objectPosition.hitVec;
				continue;
			}
			entity = e;
			ve = objectPosition.hitVec;
			range = v;
		}
		if (range < Range && !(entity instanceof EntityLivingBase) && !(entity instanceof EntityItemFrame)) {
			entity = null;
		}
		Wrapper.INSTANCE.mc().mcProfiler.endSection();
		if (entity == null || ve == null) {
			return null;
		}
		return new Object[]{entity, ve};
	}

	
	
//	@Override
//	public void onClientTick(ClientTickEvent event) {
//		 if(Wrapper.INSTANCE.mc().mcProfiler!=null){
//
//	            try {
//	                Field field = ReflectionHelper.findField(Minecraft.class, new String[]{"mcProfiler", "field_71424_I"});
//	                if (!field.isAccessible()) {
//	                    field.setAccessible(true);
//	                }
//	              net.minecraft.profiler.Profiler  profiler = (   net.minecraft.profiler.Profiler) field.get(mc);
//	                if(!(profiler instanceof ProfilerHook)){
//	                    field.set(mc,(net.minecraft.profiler.Profiler)new ProfilerHook(profiler));
//	                }
//
//	            }catch (Exception e){
//	                e.printStackTrace();
//
//	            }
//	        }
//		super.onClientTick(event);
//	}
//	
//	public static void onStartSection(String name) {
//		 if(name.equals("gameMode")){
//	       
//	            getMouseOver(1.0f);
//	        }
//		
//	}
//	public static void onEndSection(String lastSection) {
//		// TODO �Զ����ɵķ������
//		
//	}
//	public static void onEndStartSection(String lastSection) {
//		// TODO �Զ����ɵķ������
//		
//	}
//	 public static void getMouseOver(float partialTicks)
//	    {
//	        Entity entity = Wrapper.INSTANCE.mc().getRenderViewEntity();
//	        Entity pointedEntity=null;
//
//	        if (entity != null)
//	        {
//	            if (Wrapper.INSTANCE.world() != null)
//	            {
//	               Wrapper.INSTANCE.mc().mcProfiler.startSection("pick");
//	                Wrapper.INSTANCE.mc().pointedEntity = null;
//
//	                //(double)Wrapper.INSTANCE.controller().getBlockReachDistance();
//	                double d0 = reachValue.getValue();
//	               Wrapper.INSTANCE.mc().objectMouseOver = entity.rayTrace(d0, partialTicks);
//	                double d1 = d0;
//	                Vec3 vec3 = entity.getPositionEyes(partialTicks);
//	                boolean flag = false;
//	                int i = 3;
//
//	                if (Wrapper.INSTANCE.controller().extendedReach())
//	                {
//	                    d0 = 6.0D;
//	                    d1 = 6.0D;
//	                }
//	                else
//	                {
//	                    if (d0 > reachValue.getValue())
//	                    {
//	                        flag = true;
//	                    }
//	                }
//
//	                if (Wrapper.INSTANCE.mc().objectMouseOver != null)
//	                {
//	                    d1 = Wrapper.INSTANCE.mc().objectMouseOver.hitVec.distanceTo(vec3);
//	                }
//
//	                Vec3 vec31 = entity.getLook(partialTicks);
//	                Vec3 vec32 = vec3.addVector(vec31.x * d0, vec31.y * d0, vec31.z * d0);
//	                pointedEntity = null;
//	                Vec3 vec33 = null;
//	                float f = 1.0F;
//	                List<Entity> list = Wrapper.INSTANCE.world().getEntitiesInAABBexcluding(entity, entity.getEntityBoundingBox().addCoord(vec31.x * d0, vec31.y * d0, vec31.z * d0).expand((double)f, (double)f, (double)f), Predicates.and(EntitySelectors.NOT_SPECTATING, new Predicate<Entity>()
//	                {
//	                    public boolean apply(Entity p_apply_1_)
//	                    {
//	                        return p_apply_1_.canBeCollidedWith();
//	                    }
//	                }));
//	                double d2 = d1;
//
//	                for (int j = 0; j < list.size(); ++j)
//	                {
//	                    Entity entity1 = (Entity)list.get(j);
//	                    float f1 = entity1.getCollisionBorderSize();
//	                    AxisAlignedBB axisalignedbb = entity1.getEntityBoundingBox().expand((double)f1, (double)f1, (double)f1);
//	                    MovingObjectPosition movingobjectposition = axisalignedbb.calculateIntercept(vec3, vec32);
//
//	                    if (axisalignedbb.isVecInside(vec3))
//	                    {
//	                        if (d2 >= 0.0D)
//	                        {
//	                           pointedEntity = entity1;
//	                            vec33 = movingobjectposition == null ? vec3 : movingobjectposition.hitVec;
//	                            d2 = 0.0D;
//	                        }
//	                    }
//	                    else if (movingobjectposition != null)
//	                    {
//	                        double d3 = vec3.distanceTo(movingobjectposition.hitVec);
//
//	                        if (d3 < d2 || d2 == 0.0D)
//	                        {
//	                            if (entity1 == entity.ridingEntity && !entity.canRiderInteract())
//	                            {
//	                                if (d2 == 0.0D)
//	                                {
//	                                   pointedEntity = entity1;
//	                                    vec33 = movingobjectposition.hitVec;
//	                                }
//	                            }
//	                            else
//	                            {
//	                                pointedEntity = entity1;
//	                                vec33 = movingobjectposition.hitVec;
//	                                d2 = d3;
//	                            }
//	                        }
//	                    }
//	                }
//
//	                if (pointedEntity != null && flag && vec3.distanceTo(vec33) > reachValue.getValue())
//	                {
//	                    pointedEntity = null;
//	                    Wrapper.INSTANCE.mc().objectMouseOver = new MovingObjectPosition(MovingObjectPosition.MovingObjectType.MISS, vec33, (EnumFacing)null, new BlockPos(vec33));
//	                }
//
//	                if (pointedEntity != null && (d2 < d1 || Wrapper.INSTANCE.mc().objectMouseOver == null))
//	                {
//	                    Wrapper.INSTANCE.mc().objectMouseOver = new MovingObjectPosition(pointedEntity, vec33);
//
//	                    if (pointedEntity instanceof EntityLivingBase || pointedEntity instanceof EntityItemFrame)
//	                    {
//	                        Wrapper.INSTANCE.mc().pointedEntity = pointedEntity;
//	                    }
//	                }
//	                ReflectionHelper.setPrivateValue(EntityRenderer.class,Wrapper.INSTANCE.mc().entityRenderer,pointedEntity,new String[]{"pointedEntity","field_78528_u"});
//	               // Wrapper.INSTANCE.mc().mcProfiler.endSection();
//	            }
//	        }
//	    }
//	
	
}
